package com.yeskery.nut.bean;

import com.yeskery.nut.scan.AnnotationHandler;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * bean定义注册器
 * @author sprout
 * @version 1.0
 * 2022-08-24 10:25
 */
public interface BeanDefinitionRegistry {

    /**
     * 获取支持的注解类型
     * @return 支持的注解类型
     */
    default Set<Class<? extends Annotation>> getSupportAnnotations() {
        return getSupportAnnotationHandlerMap().keySet();
    }

    /**
     * 获取支持的注解处理器map
     * @return 注解处理器map
     */
    Map<Class<? extends Annotation>, AnnotationHandler> getSupportAnnotationHandlerMap();

    /**
     * 获取支持的注解处理器
     * @param annotationClass 注解类型
     * @return 支持的注解处理器
     */
    default AnnotationHandler getSupportAnnotationHandler(Class<? extends Annotation> annotationClass) {
        if (annotationClass == null) {
            throw new BeanException("Bean Definition Annotation Class Must Not Be Null.");
        }
        return getSupportAnnotationHandlerMap().get(annotationClass);
    }

    /**
     * 获取当前的所有注解bean定义
     * @return 当前的所有注解bean定义
     */
    Map<Class<? extends Annotation>, Collection<Class<?>>> getAnnotationBeanDefinitions();

    /**
     * 是否已经存在指定的bean定义对象
     * @param annotationClass 支持的注解类对象
     * @param beanClass bean类型对象
     * @return 是否注册成功
     */
    default boolean hasBeanDefinition(Class<? extends Annotation> annotationClass, Class<?> beanClass) {
        if (annotationClass == null) {
            throw new BeanException("Bean Definition Annotation Class Must Not Be Null.");
        }
        if (!getSupportAnnotations().contains(annotationClass)) {
            throw new BeanException("UnSupport Bean Definition Annotation Class [" + annotationClass.getName() + "]");
        }
        return getAnnotationBeanDefinitions().get(annotationClass).contains(beanClass);
    }

    /**
     * 注册bean定义对象，可覆盖已经注册的bean定义对象
     * @param annotationClass 支持的注解类对象
     * @param beanClass bean类型对象
     * @return 是否注册成功
     */
    default boolean registerBeanDefinition(Class<? extends Annotation> annotationClass, Class<?> beanClass) {
        if (annotationClass == null) {
            throw new BeanException("Bean Definition Annotation Class Must Not Be Null.");
        }
        if (!getSupportAnnotations().contains(annotationClass)) {
            throw new BeanException("UnSupport Bean Definition Annotation Class [" + annotationClass.getName() + "]");
        }
        return getAnnotationBeanDefinitions().get(annotationClass).add(beanClass);
    }

    /**
     * 移除bean定义对象
     * @param annotationClass 支持的注解类对象
     * @param beanClass bean类型对象
     * @return 是否移除成功
     */
    default boolean removeBeanDefinition(Class<? extends Annotation> annotationClass, Class<?> beanClass) {
        if (annotationClass == null) {
            throw new BeanException("Bean Definition Annotation Class Must Not Be Null.");
        }
        if (!getSupportAnnotations().contains(annotationClass)) {
            throw new BeanException("UnSupport Bean Definition Annotation Class [" + annotationClass.getName() + "]");
        }
        Collection<Class<?>> collection = getAnnotationBeanDefinitions().get(annotationClass);
        if (!collection.contains(beanClass)) {
            return false;
        }
        Iterator<Class<?>> iterator = collection.iterator();
        while (iterator.hasNext()) {
            Class<?> clazz = iterator.next();
            if (clazz.equals(beanClass)) {
                iterator.remove();
                return true;
            }
        }
        return false;
    }
}
